const genderMap = {
  1: '男',
  2: '女'
}
const getValueByProp = (row, prop) => {
  const values = prop.split(/\.|\[|]\[|]\./)
  let res = row
  while (values.length) {
    res = Reflect.get(res, values.shift())
  }
  return res
}
const isFunction = (fn) => {
  return typeof fn === 'function'
}

const hidden = ref(false)
const columns = ref([
  { label: 'id', prop: 'id', statistics: 'text' },
  {
    label: '姓名',
    prop: 'name[0].name'
  },
  {
    label: '年龄',
    prop: 'age',
    statistics: 'average',
    render: (row) => <mark>{row.age}</mark>,
    renderHeader: (row) => <span>{row.label}</span>
  },
  { label: '性别', prop: 'gender', format: (row) => genderMap[row.gender] },
  { label: '邮箱', prop: 'email', hidden: () => hidden.value },
  { label: '地址', prop: 'address', format: (row) => row.city + row.district + row.street }
])
const columnsComp = computed(() => {
  return columns.value.filter((item) => (isFunction(item.hidden) ? !item.hidden() : !item.hidden))
})
const data = ref([
  {
    id: 1,
    name: [{ name: '张三' }],
    age: 18,
    gender: 1,
    city: '北京',
    district: '朝阳区',
    street: 'xx街道'
  },
  {
    id: 2,
    name: [{ name: '李四' }],
    age: 20,
    gender: 2,
    city: '上海',
    district: '浦东新区',
    street: 'xx街道'
  }
])
const statistics = computed(() => {
  return columnsComp.value.map((item) => {
    if (item.statistics === 'sum') {
      return data.value.reduce((prev, curr) => {
        return prev + curr[item.prop]
      }, 0)
    }
    if (item.statistics === 'average') {
      return (
        data.value.reduce((prev, curr) => {
          return prev + curr[item.prop]
        }, 0) / data.value.length
      )
    }
    if (item.statistics === 'max') {
      return Math.max(...data.value.map((item) => item[item.prop]))
    }
    if (item.statistics === 'min') {
      return Math.min(...data.value.map((item) => item[item.prop]))
    }
    if (item.statistics === 'text') {
      return '合计'
    }
    return undefined
  })
})
export default () => {
  return (
    <>
      <button onClick={() => (hidden.value = !hidden.value)}>
        {hidden.value ? '显示' : '隐藏'}
      </button>
      {data.value.length ? (
        <table style="border: 2px solid #42b983;border-radius: 3px;background-color: #fff;">
          <thead>
            {columnsComp.value.map(({ renderHeader, ...item }) => (
              <th style="background-color: #42b983; color: rgba(255, 255, 255, 0.66); cursor: pointer; user-select: none; min-width: 120px; padding: 10px 20px;">
                {renderHeader ? renderHeader(item) : item.label}
              </th>
            ))}
          </thead>
          <tbody>
            {data.value.map((row, rowIndex) => (
              <tr>
                {columnsComp.value.map(({ render, format, ...column }, colIndex) => (
                  <td style="background-color: #f9f9f9; padding: 10px 20px; min-width: 120px;">
                    {render
                      ? render(row, column, rowIndex, colIndex)
                      : format
                        ? format(row, column)
                        : getValueByProp(row, column.prop)}
                  </td>
                ))}
              </tr>
            ))}
          </tbody>
          {statistics.value?.length > 0 && (
            <tfoot>
              {statistics.value.map((row) => (
                <td style="background-color: #f9f9f9; padding: 10px 20px; min-width: 120px;">
                  {row}
                </td>
              ))}
            </tfoot>
          )}
        </table>
      ) : (
        <div style="text-align: center; padding: 20px;">暂无数据</div>
      )}
    </>
  )
}
